package com.example.questionnaire.mbg.service.impl;

import com.example.questionnaire.dto.QuestionDTO;
import com.example.questionnaire.dto.WantDTO;
import com.example.questionnaire.exception.NotFindException;
import com.example.questionnaire.mbg.entity.Enum.OptionTypeEnum;
import com.example.questionnaire.mbg.entity.Enum.QuestionTypeEnum;
import com.example.questionnaire.mbg.entity.Option;
import com.example.questionnaire.mbg.entity.Question;
import com.example.questionnaire.mbg.entity.Want;
import com.example.questionnaire.mbg.mapper.OptionMapper;
import com.example.questionnaire.mbg.mapper.QuestionMapper;
import com.example.questionnaire.mbg.service.IOptionService;
import com.example.questionnaire.mbg.service.IQuestionService;
import com.example.questionnaire.mbg.service.IWantService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Primary
@Service
public class QuestionServiceImpl implements IQuestionService {

    @Resource
    private QuestionMapper questionMapper;


    @Resource
    private IOptionService optionService;

    @Resource
    private OptionMapper optionMapper;

    @Resource
    private IWantService wantService;

    @Override
    public void create(QuestionDTO dto, int questionNumber, int questionnaireId) {
        String questionType = dto.getType();
        QuestionTypeEnum qType = QuestionTypeEnum.fromString(questionType);

        List<String> choices = dto.getChoices();
        int number = dto.getNumber();
        String text = dto.getText();

        Question question = Question.builder()
                .questionnaireId(questionnaireId)
                .questionType(qType)
                .receiveCnt(0)
                .nullable(dto.getNullable())
                .content(dto.getTitle())
                .description(dto.getDescription())
                .questionNumber(questionNumber)
                .score(dto.getScore())
                .uuid(dto.getUuid())
                .hide(dto.getHide())
                .interlockCombinator(dto.getInterlock_combinator())
                .build();


        questionMapper.create(question);
        int qid = question.getId();

        switch (qType) {
            case LOCATION:
            case INPUT: {
                Option option = Option.builder()
                        .content(text)
                        .questionId(qid)
                        .optionType(OptionTypeEnum.INPUT)
                        .optionNumber(0)
                        .answerText(dto.getInput_answer())
                        .build();

                optionService.create(option);
                break;
            }
            case RATING: {
                for (int idx = 0; idx <= number; idx++) {
                    Option option = Option.builder()
                            .content(String.valueOf(idx))
                            .questionId(qid)
                            .optionType(OptionTypeEnum.SELECT)
                            .optionNumber(idx)
                            .build();

                    optionService.create(option);
                }
                break;
            }
            case RADIO: {
                int idx = 0;
                for (String choice : choices) {
                    Option option = Option.builder()
                            .content(choice)
                            .questionId(qid)
                            .optionType(OptionTypeEnum.SELECT)
                            .optionNumber(idx)
                            .isRight(dto.getRadio_answer() == idx)
                            .capacity(dto.getCapacity().get(idx))
                            .build();

                    optionService.create(option);
                    idx++;
                }
                break;
            }

            case CHECKBOX: {
                int idx = 0;
                for (String choice : choices) {
                    Option option = Option.builder()
                            .content(choice)
                            .questionId(qid)
                            .optionType(OptionTypeEnum.SELECT)
                            .optionNumber(idx)
                            .isRight(inArray(dto.getCheckbox_answer(), idx))
                            .capacity(dto.getCapacity().get(idx))
                            .build();

                    optionService.create(option);
                    idx++;
                }
                break;
            }

            default: {
                throw new NotFindException("questionType");
            }
        }

        for (WantDTO wantDTO : dto.getWants()) {
            String masks = "";
            for (Integer mask : wantDTO.getMask()) {
                masks = masks + mask + ",";
            }
            Want want = Want.builder()
                    .inverted(wantDTO.getInverted())
                    .mask(masks)
                    .uuid(wantDTO.getUuid())
                    .questionId(qid)
                    .build();

            wantService.create(want);
        }
    }

    private Boolean inArray(ArrayList<Integer> list, int idx) {
        for (Integer i : list) {
            if (i == idx) return true;
        }
        return false;
    }

    @Override
    public void update(int qnid, int questionNumber, QuestionDTO dto) {

        QuestionTypeEnum qType = QuestionTypeEnum.fromString(dto.getType());

        List<String> choices = dto.getChoices();
        String text = dto.getText();

        Question question = Question.builder()
                .questionNumber(questionNumber)
                .description(dto.getDescription())
                .nullable(dto.getNullable())
                .content(dto.getTitle())
                .score(dto.getScore())
                .build();
        questionMapper.update(question);

        int qid = getByQuestionNumber(qnid, questionNumber).getId();
        Option option;
        switch (qType) {
            case INPUT:
                option = Option.builder().optionNumber(0).questionId(qid).content(text).build();
                optionService.update(option);
            case RATING:
                break;
            case RADIO:
            case CHECKBOX: {
                int idx = 0;
                for (String choice : choices) {
                    option = Option.builder().optionNumber(idx++).questionId(qid).content(choice).build();
                    optionService.update(option);
                }
                break;
            }

            default: {
                throw new NotFindException("questionType");
            }
        }
    }

    @Override
    public Question getByQuestionNumber(int questionnaireId, int questionNumber) {
        return questionMapper.getByQuestionNumber(questionnaireId, questionNumber);
    }

    @Override
    public void delete(int id) {
        questionMapper.delete(id);
    }

    @Override
    public Question get(int id) {
        return questionMapper.get(id);
    }

    @Override
    public List<Question> listAll(int qnid) {
        return questionMapper.listAll(qnid);
    }

    @Override
    public void incReceiveCnt(int qid) {
        questionMapper.incReceiveCnt(qid);
    }

    @Override
    public void remove(int qid) {
        delete(qid);
        optionService.deleteBYQid(qid);
    }

    @Override
    public void copy(Question question) {
        List<Option> options = optionService.listAll(question.getId());
        questionMapper.create(question);
        for (Option option : options) {
            option.setQuestionId(question.getId());
            optionMapper.create(option);
        }
    }
}